배경
최근에 개발자 인생의 멘토인 머신러닝 개발자 형과 함께 프로젝트를 1달 정도 진행했다. 짧은 시간이지만 이 시간에도 많은 것을 생각하게 해준 시간이었다.
프로젝트의 주제는 PDF Viewer기반으로 지식들을 정리할 수 있는 Zotero같은 서비스의 고도화 버전을 만드는 일이었다. PDF기반으로 공부할 때 Annotation을 만들면서 우리는 기록을 한다. 하지만, 지식들의 연관관계를 만들기는 어려워서 지식의 파편화가 일어나는 문제가 있었다. 그것을 해결해 줄 수 있는 서비스였다.
요구사항의 정의는 중요하다.
Swift
이 서비스는 PDF에서 Drawing이 기본적으로 필요했다. 그래서 PDF를 가장 많이 보고 필기하는 사용자층이 많은 타겟으로 IOS 앱을 개발하기로 했다. 서비스를 만들기 위해 Swift를 공부했다. 정확히 말하면 SwiftUI부터 공부했다.
2019년에 공개한 SwiftUI를 이용해서 빠르게 UI를 만들면 PoC 또한 빠르게 만들 수 있을 것 같다는 생각이었다. 하지만, 알면 알수록 비즈니스적인 로직들을 구현하기 위해서 결과적으로는 Swift를 알아야만 제대로 된 앱을 구축할 수 있었다. Object-c기반인 Swift를 공부하면서 오랜만에 객체지향 프로그래밍을 해서 재밌었다.
1주일 정도 학습을 했을 때 방향을 바꾸기로 했다. 더 빠르게 PoC를 보기 위해서 + Drawing보다는 Annotation이 더 메인 기능이었기 때문에 웹 기술로 개발하는 것이 더 적합할 것 같다는 의견이었다.
WebApp
그렇게 웹에서도 동작하고 추후 앱에서도 동작가능하도록 WebApp을 만들기로 했다. 하지만, 금방 방향을 바꿨는데 LLM모델을 돌리기 위해서 데스크탑 앱 형태로 개발하는 것이 더 좋을 것 같다고 판명되서 Electron으로 데스크탑 앱을 개발하고 오픈소스 형태로 배포해서 많은 사람들에게 도움을 줄 수 있는 방향으로 바꿨다.
Desktop App
빠르게 PoC를 개발하기 위해서 Electron + Vite + React BoilerPlate를 제공하는 곳을 찾았고 최근까지 관리되고 있는 곳으로 최종 선정했다. 처음에는 가장 기본적인 PDF Viewer 라이브러리만 가져오고 그 외의 기능은 직접 구현을 했다.
하지만, 만들다보니 우리의 목표인 “빠르게 PoC를 만들고 세상에 공개해서 효용성이 있는지 판단한다”는 기준에 어긋났다. 그래서 더 완벽한 PDF를 찾아나서기 시작했다. 하지만, 생각보다 완벽한 라이브러리일수록 우리가 구현하고자 하는 기능을 추가하기 어려웠다. Contributor가 되어 기여를 하고 싶어도 더 이상 라이브러리를 관리 하고 있지 않았다.
그러던 찰나, Mozilla에서 운영하는 PDF.js를 만나게 되었고 대부분의 PDF Viewer들이 내부적으로 이것을 사용한다는 것을 알게 됐다. Vanilla Javascript로 짜여져 있어서 iframe으로 사용하지 않는 이상 리액트에 호환시키기에는 어려웠다. iframe을 사용하면 여러 기술적 제약이 생기게 되기 때문에 vanilla javascript로 개발하기로 했다.
완벽한 검색기능?
검색 기능은 LLM을 사용해보면 거의 완벽하다고 볼 수 있다. 실제로 Google의 사용비율이 계속 낮아지고 있고 Perplexity나 ChatGPT에서 Web을 체크하고 검색하는 것이 빠르다. 하지만 “어떤 것을 검색할지” 명확히 지시를 내려주는 것은 여전히 개발자의 몫이다.
우리는 시작할 때부터 잘못된 방향으로 가고 있었던 건지도 모른다. zotero는 오픈소스다. 비슷한 서비스를 빠르게 만들어서 PoC를 보는 것보다 이미 오픈소스인 zotero를 기반으로 해서 고도화해보는 것이 더 좋은 방향이었을지 모른다.
그것이 바로 zotero/reader였다. 기본 기능들이 완벽했고 최신 버전인 7버전에서는 우리가 구현하고자 생각했던 것의 일부가 구현되어 있었다.
플러그인을 개발하는 방향으로 전환
우리는 개발 도중에 오픈소스로 많은 사용자에게 도움을 줄 수 있는 방향으로 바꿨다. 그렇다면 이미 base가 훌륭한 zotero를 두고 새로 또 지식을 관리할 수 있는 앱을 만들 필요가 없었다.
그래서, Zotero의 플러그인을 개발하기로 했다. 이제 핵심 기능에 집중해서 개발하면 된다.
먼 길을 돌아왔다.
처음부터 사업이나 크게 돈을 벌 목적으로 시작한 것은 아니고 경험해보자는 취지에서 시작한 것이기 때문에 이렇게 잦은 변경에도 즐거웠고, 배우는 것도 많았다.
앞으로 무엇을 공부해야 하나
zotero 플러그인 개발 방법과 Rag, LangChain쪽을 알아볼 예정이다. 앞으로 AI는 우리 삶에 없어서는 안될 무엇인가가 되있을 것이기 때문에 시대에 뒤쳐지지 않기 위해 더 잘 사용하는 방법을 알아야 한다고 생각하고 있었는데 좋은 기회인 것 같다.
사람을 다루는 것은 어렵다.
대학교 때 사람들을 이끄는 소프트능력을 개발하고 싶어서 조장을 맡은 경험이 여러번 있다.
그 때 얻었던 가장 큰 교훈은 아무것도 못하는 사람은 없고, 사람마다 잘하는 영역이 “다르다”라는 것이었다. 그리고 그것을 잘 이끌어내줄 수 있는 것이 팀장이 해야 하는 가장 중요한 일이라는 점을 배웠다. 그렇기 때문에 항목을 정해서 지시하는 것도 중요하지만, 각자의 강점을 발휘할 수 있도록 자발적인 참여를 유도하는 것이 중요했었던 기억이 있다.
개발자가 된 이후 몇 번의 팀 프로젝트를 시도하면서 느낀 것은 생각보다 내가 가진 아이디어를 상대방에게 설득시키기가 쉽지 않다는 것이다.
여성 여행자를 위한 앱을 개발한 노매드걸 대표님은 한국에서 투자를 받고 사업을 계획하신 것으로 알고 있는데, 투자자들이 이미 수많은 여행 앱이 있는데 왜 여성 전용이 나와야 하는지 이해하지 못하자 해외에서 사업을 하셨고 성공하신 케이스다.
정확한 비교군은 아니겠지만, 각잡고 아이디어를 설명해도 상대방은 이해를 못할 수 있기 때문에 내가 생각하고 있는 그림을 간추려서 전달하는 것은 내가 그리고 있는 그림의 일부도 이해 못할 수 있다.
살아온 방식이 다르기도 하고 우리는 모두 다른 배경지식을 가지고 있기 때문에 설명하는 것은 엄청난 정성이 들어가는 일이다.
이번에 이 프로젝트 진행을 제의 받았을 때 지식의 파편화라는 관점에서는 완전 공감을 했지만, Zotero같은 서비스를 이용해보지 않아서 이해가 쉽지 않았다.
그래서 어떻게 해결했나?
두 가지가 컸다.
- 궁금한 것을 바로바로 물어봤고 그 때마다 친절하게 대답해주셨다.
- 내가 이해한 내용이 맞는지 Figma나 Freeform를 이용해 와이어프레임이나 유저 플로우로 그리고 소통을 요청했다. 그랬더니 불필요한 개발을 하지 않고 서로의 생각을 좁히며 기능 개발을 할 수 있었다.
이번 프로젝트에서 빠르게 PoC를 만들기 위해 했던 방법
요즘 가장 핫한 Cursor를 사용하는 것이다. Github Copilot, WindSurf, Cursor 3개를 평소에 조금씩 테스트 해봤을 때 코드 베이스를 이해하는 점과 수정해주는 방향 및 프로세스 부분에서 가장 우수했기 때문에 Cursor를 시작부터 사용하기로 했다.
회사에서 Cursor 계정을 배포해줘서 큰 규모의 서비스들에서 사용해봤을 때는 코드베이스 전부를 이해하기에 토큰의 한계가 있는지 큰 그림은 이해하지 못하길래 부분적으로만 도움을 받았다.
하지만, 이번에는 범위가 작기 때문에 기대가 컸고 어느정도는 그 기대에 부합했다. 완벽하지는 않지만 훌륭한 동료 한명과 페어플레이로 개발을 하는 느낌이었다. 아래는 경험했을 때 유용하게 Cursor를 사용하는 방법이다.
- 최신 버전의 Cursor에서는 rule을 여러개로 쪼개서 명령이 가능하다. 구조, 기술적인 부분이나 컨벤션 같은 부분들을 나눠서 지시하거나 항상 인지하고 있어야 할 프롬프트를 주입해놓는 것과 같다. 미리 자세하게 써놓으면 써놓을수록 반복적으로 챗을 나눌 때 입력해야 하는 양이 적을 수 있다.
- 대화를 나눌 때 두루뭉실하게 얘기하지 않고, 정확히 얘기할수록 내가 원하는 답변을 받을 확률이 올라간다.
- 수정하고자 하는 범위는 작게 여러번 가져가는 것이 좋다.
- 한번의 채팅에서 몇 번 대화하다보면 점점 원하는 답변을 받기 어려워지는 순간이 있다. 그 때 @Summarized Composers 기능을 사용하거나 이전 채팅의 마지막에 요약해달라고 한 다음에 받은 답변을 새 채팅에 옮겨서 이어서 대화할 수 있다.
- 특정 기술스택을 사용하려는 경우 공식문서 링크를 @Docs에 주입하면 신뢰있는 답변을 얻을 수 있다.
- Composer를 쓸 때는 claude-3.5-sonnet를 쓰고, 복잡한 질문에 대해서는 Chat에서 o1을 사용하자.
후기
- Cursor는 분명 대단하다. 하지만 완벽하지 않다. 앞으로 몇년 뒤에는 어떻게 될지 모르겠지만, 아직까지 개발자를 100% 대체할 수 없다고 사용할수록 느낀다. 복잡하지 않고 일반적으로 많이 내릴만한 태스크들, feature단위 명령에 대해서는 잘 수행해주지만 복잡한 명령, 디테일한 부분들에 대해서는 아직 완벽하지 못하다고 느껴진다.
- Cursor와 대화하다보면 복잡한 명령을 풀어내기 위해 디테일한 설명을 할 수 있는 언어 능력이 자연스럽게 늘어난다. 내 언어 능력이 향상될수록, 이 친구의 개발 능력이 향상되는 것이 느껴진다.
- Trello를 이번에 처음 써봤는데 Jira의 간소화된 버전같으면서도 충분히 파워풀한 기능인 것 같고 무엇보다 무료라는게 놀라웠다.
- 최근에 회사일이 바빴다 보니 사이드 프로젝트에 많은 시간을 투자하지 못할 때가 많아서 미안한 감정이 들 때가 있었다. 그때마다 재밌게 하면 된다는 말이 더 큰 힘이 되어 10시에 퇴근해도 새벽까지 재밌게 할 수 있게 해주는 것 같다.
- 조금씩 사이드 프로젝트를 하는 것이 오히려 회사에서 회사일에 더욱 집중하게 만들어주는 것 같다. 앞으로 더 많은 것을 해낼 수 있을 것 같은 긍정적인 에너지가 생긴다!